package com.mce.nebula.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mce.nebula.common.JSONUtil;
import com.mce.nebula.entity.ConsoleSysConfig;
import com.mce.nebula.entity.Enterprise;
import com.mce.nebula.repository.ConsoleSysConfigRepository;
import com.mce.nebula.repository.EnterpriseRepository;
import com.mce.nebula.security.UserDetailsImpl;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 配置管理服务
 * 对应Python的ConfigOSSView, ConfigRUDView, LogoView功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ConfigService {

    private final ConsoleSysConfigRepository configRepository;
    private final EnterpriseRepository enterpriseRepository;
    private final ObjectMapper objectMapper;

    // 平台配置键列表
    private static final List<String> BASE_CFG_KEYS = List.of(
            "ENTERPRISE_ID", "TITLE", "LOGO", "FAVICON", "DOCUMENT",
            "HEADER_COLOR", "HEADER_WRITING_COLOR", "SIDEBAR_COLOR",
            "SIDEBAR_WRITING_COLOR", "FOOTER", "LOGIN_IMAGE",
            "OFFICIAL_DEMO", "CAPTCHA_CODE"
    );

    private static final List<String> CFG_KEYS = List.of(
            "SHADOW", "OSS_CONFIG"
    );


    public List<ConsoleSysConfig> findAll() {
        return this.configRepository.findAll();
    }

    public long count() {
        return this.configRepository.count();
    }

    /**
     * 获取OSS配置
     */
    public Map<String, Object> getOSSConfig() {
        Optional<ConsoleSysConfig> ossConfig = configRepository.findByKey("OSS_CONFIG");
        if (ossConfig.isPresent()) {
            try {
                return objectMapper.readValue(ossConfig.get().getValue(), new TypeReference<Map<String, Object>>() {
                });
            } catch (Exception e) {
                log.error("Failed to parse OSS config JSON", e);
                return new HashMap<>();
            }
        }
        return new HashMap<>();
    }

    /**
     * 更新OSS配置
     */
    @Transactional
    public Map<String, Object> updateOSSConfig(Map<String, Object> config) {
        Optional<ConsoleSysConfig> existingConfig = configRepository.findByKey("OSS_CONFIG");

        if (existingConfig.isPresent()) {
            // 更新现有配置
            ConsoleSysConfig ossConfig = existingConfig.get();
            ossConfig.setValue(convertToJsonString(config));
            ossConfig.setDescription("OSS 配置");
            ossConfig.setCreateTime(LocalDateTime.now());
            configRepository.save(ossConfig);

            Map<String, Object> result = new HashMap<>();
            result.put("message", "配置更新成功");
            return result;
        } else {
            // 创建新配置
            ConsoleSysConfig newConfig = new ConsoleSysConfig();
            newConfig.setKey("OSS_CONFIG");
            newConfig.setType("json");
            newConfig.setValue(convertToJsonString(config));
            newConfig.setDescription("OSS 配置");
            newConfig.setCreateTime(LocalDateTime.now());
            newConfig.setEnterpriseId("");

            ConsoleSysConfig savedConfig = configRepository.save(newConfig);

            Map<String, Object> result = new HashMap<>();
            result.put("message", "配置创建成功");
            result.put("config_id", savedConfig.getId());
            return result;
        }
    }


    public record ConfigInfo(
            Boolean enable,
            Object value
    ) {
    }


    public Map<String, Object> getConfigInfo() {
        final Map<String, Object> data = getPlatformConfig();

        // 获取当前用户信息
        try {
            UserDetailsImpl userDetails = getCurrentUser();
            if (userDetails != null) {
                data.put("enterprise_id", userDetails.getEnterpriseId());

                // 获取企业配置
                Map<String, Object> entConfig = getEnterpriseConfig(userDetails.getEnterpriseId());
                data.putAll(entConfig);
            }
        } catch (Exception e) {
            log.debug("No authenticated user found");
        }

        List<ConsoleSysConfig> allConfigs = this.configRepository.findAll();
        if (allConfigs != null) {
            allConfigs.stream().forEach(config -> {
                if (config.getType().equals("bool")) {
                    data.put(config.getKey(), new ConfigInfo(config.getEnable(), Boolean.parseBoolean(config.getValue())));
                } else if (config.getType().equals("object")) {
                    data.put(config.getKey(), new ConfigInfo(config.getEnable(), JSONUtil.stringToObject(config.getValue(), HashMap.class)));
                } else if (config.getType().equals("array")) {
                    data.put(config.getKey(), new ConfigInfo(config.getEnable(), JSONUtil.stringToObject(config.getValue(), ArrayList.class)));
                } else {
                    data.put(config.getKey(), new ConfigInfo(config.getEnable(), config.getValue()));
                }

            });
        }
        // 设置环境变量配置
        data.put("is_disable_logout", getEnvBoolean("IS_DISABLE_LOGOUT", false));
        data.put("is_offline", getEnvBoolean("IS_OFFLINE", false));
        data.put("sso_enable", getEnvBoolean("SSO_ENABLE", false));
        data.put("diy", getEnvBoolean("DIY", true));
        data.put("enable_yum_oauth", getEnvBoolean("ENABLE_YUM_OAUTH", false));
        data.put("diy_customer", getEnvString("DIY_CUSTOMER", "rainbond"));
        data.put("is_delivery_version", getEnvBoolean("IS_DELIVERY_VERSION", false));

        if (getEnvString("USE_SAAS", null) != null) {
            data.put("is_saas", true);
        }

        return data;
    }

    /**
     * 获取平台配置
     */
    private Map<String, Object> getPlatformConfig() {
        Map<String, Object> data = new HashMap<>();

        // 设置默认企业ID
        String enterpriseId = getEnvString("ENTERPRISE_ID", "");
        data.put("enterprise_id", enterpriseId);

        // 处理shadow配置
        Optional<ConsoleSysConfig> shadowConfig = configRepository.findByKey("SHADOW");
        if (shadowConfig.isPresent() && StringUtils.isNotEmpty(shadowConfig.get().getValue())) {
            try {
                Map<String, Object> shadowValue = objectMapper.readValue(
                        shadowConfig.get().getValue(),
                        new TypeReference<Map<String, Object>>() {
                        }
                );
                Object value = shadowValue.get("value");
                if (value != null) {
                    boolean shadowEnabled = "true".equalsIgnoreCase(value.toString());
                    Map<String, Object> shadow = new HashMap<>();
                    shadow.put("enable", shadowEnabled);
                    shadow.put("value", shadowEnabled);
                    data.put("shadow", shadow);
                }
            } catch (Exception e) {
                log.error("Failed to parse shadow config", e);
            }
        }

        return data;
    }

    /**
     * 获取企业配置
     */
    private Map<String, Object> getEnterpriseConfig(String enterpriseId) {
        Map<String, Object> data = new HashMap<>();

        if (enterpriseId == null || enterpriseId.trim().isEmpty()) {
            return data;
        }

        try {
            Optional<Enterprise> enterprise = enterpriseRepository.findByEnterpriseId(enterpriseId);
            if (enterprise.isPresent()) {
                Enterprise ent = enterprise.get();
                data.put("title", ent.getEnterpriseName());
                data.put("logo", ent.getLogo());
                data.put("favicon", ent.getFavicon());
                data.put("document", ent.getDocument());
                data.put("header_color", ent.getHeaderColor());
                data.put("header_writing_color", ent.getHeaderWritingColor());
                data.put("sidebar_color", ent.getSidebarColor());
                data.put("sidebar_writing_color", ent.getSidebarWritingColor());
                data.put("footer", ent.getFooter());
                data.put("login_image", ent.getLoginImage());
                data.put("official_demo", ent.getOfficialDemo());
                data.put("captcha_code", ent.getCaptchaCode());
            }
        } catch (Exception e) {
            log.error("Failed to get enterprise config for: {}", enterpriseId, e);
        }

        return data;
    }

    /**
     * 更新配置
     */
    @Transactional
    public Map<String, Object> updateConfig(String key, Object value) {
        String upperKey = key.toUpperCase();

        // 检查是否为可更新的配置项
        if (BASE_CFG_KEYS.contains(upperKey) || CFG_KEYS.contains(upperKey)) {
            Optional<ConsoleSysConfig> existingConfig = configRepository.findByKey(upperKey);

            if (existingConfig.isPresent()) {
                // 更新现有配置
                ConsoleSysConfig config = existingConfig.get();
                config.setValue(convertToJsonString(value));
                config.setCreateTime(LocalDateTime.now());
                configRepository.save(config);
            } else {
                // 创建新配置
                ConsoleSysConfig newConfig = new ConsoleSysConfig();
                newConfig.setKey(upperKey);
                newConfig.setType("string");
                newConfig.setValue(convertToJsonString(value));
                newConfig.setDescription("系统配置");
                newConfig.setCreateTime(LocalDateTime.now());
                newConfig.setEnterpriseId("");
                configRepository.save(newConfig);
            }

            Map<String, Object> result = new HashMap<>();
            result.put("key", upperKey);
            result.put("value", value);
            return result;
        } else {
            throw new RuntimeException("配置项不存在或不可更新: " + upperKey);
        }
    }

    /**
     * 删除配置
     */
    @Transactional
    public Map<String, Object> deleteConfig(String key) {
        String upperKey = key.toUpperCase();

        // 检查是否为可删除的配置项
        if (CFG_KEYS.contains(upperKey)) {
            Optional<ConsoleSysConfig> existingConfig = configRepository.findByKey(upperKey);

            if (existingConfig.isPresent()) {
                configRepository.delete(existingConfig.get());

                Map<String, Object> result = new HashMap<>();
                result.put("key", upperKey);
                result.put("deleted", true);
                return result;
            } else {
                throw new RuntimeException("配置项不存在: " + upperKey);
            }
        } else {
            throw new RuntimeException("配置项不可删除: " + upperKey);
        }
    }

    /**
     * 获取Logo信息
     */
    public Map<String, String> getLogo(HttpServletRequest request) {
        Map<String, String> logoInfo = new HashMap<>();

        try {
            // 从配置中获取Logo信息
            Optional<ConsoleSysConfig> logoConfig = configRepository.findByKey("LOGO");
            String logoPath = "/static/images/logo.png"; // 默认Logo路径

            if (logoConfig.isPresent()) {
                try {
                    String logoValue = logoConfig.get().getValue();
                    // 如果配置值是JSON格式，解析它
                    if (logoValue.startsWith("{") || logoValue.startsWith("\"")) {
                        logoValue = objectMapper.readValue(logoValue, String.class);
                    }
                    logoPath = logoValue;
                } catch (Exception e) {
                    log.warn("Failed to parse logo config, using default", e);
                }
            }

            // 构建完整的Logo URL
            String hostName = request.getServerName() + ":" + request.getServerPort();
            String logoUrl = "http://" + hostName + logoPath;
            logoInfo.put("logo", logoUrl);

        } catch (Exception e) {
            log.error("Failed to get logo", e);
            logoInfo.put("logo", "/static/images/logo.png");
        }

        return logoInfo;
    }

    /**
     * 获取当前用户
     */
    private UserDetailsImpl getCurrentUser() {
        try {
            return (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取环境变量布尔值
     */
    private boolean getEnvBoolean(String key, boolean defaultValue) {
        String value = System.getenv(key);
        if (value == null) {
            return defaultValue;
        }
        return "true".equalsIgnoreCase(value);
    }

    /**
     * 获取环境变量字符串值
     */
    private String getEnvString(String key, String defaultValue) {
        String value = System.getenv(key);
        return value != null ? value : defaultValue;
    }

    /**
     * 将对象转换为JSON字符串
     */
    private String convertToJsonString(Object obj) {
        try {
            if (obj instanceof String) {
                return (String) obj;
            }
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("Failed to convert object to JSON string", e);
            return obj.toString();
        }
    }
}
